﻿using System.Diagnostics;
using Microsoft.EntityFrameworkCore;

namespace HelenServer.Migrator;

public class MigrateProvider
{
    public static ZentaoDbContext? Context { get; private set; }
    public static Cache DbCache { get; private set; } = null!;


    private static bool _isStarted = false;

    public static void ReadyToMigrate(ZentaoDbOptions options)
    {
        if (_isStarted)
        {
            return;
        }

        var connectionString = $"allowzerodatetime=False;" +
            $"server={options.IP};port={options.DbPort};database=zentao;user id={options.DbUser};password={options.DbPassword};characterset=utf8;convertzerodatetime=True";

        Context = new Lazy<ZentaoDbContext>(() =>
        {
            var context = new ZentaoDbContext(
                new DbContextOptionsBuilder<ZentaoDbContext>()
                    .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTrackingWithIdentityResolution)
                    .AddInterceptors(new DefaultIntercepter())
                    .UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)).Options);

            DbCache = new Cache(context);

            return context;
        }).Value;

        _isStarted = true;
    }

    public static async Task EndMigrationAsync()
    {
        if (_isStarted && Context is not null)
        {
            await Context.DisposeAsync();
            DbCache?.Dispose();
        }
    }

    public class Cache
    {
        public ZtAction[] ZtActions { get; set; }
        public ZtBug[] ZtBugs { get; set; }
        public ZtDept[] ZtDepts { get; set; }
        public ZtFile[] ZtFiles { get; set; }
        public ZtGroup[] ZtGroups { get; set; }
        public ZtHistory[] ZtHistory { get; set; }
        public ZtLang[] ZtLangs { get; set; }
        public ZtModule[] ZtModules { get; set; }
        public ZtProduct[] ZtProducts { get; set; }
        public ZtRelease[] ZtReleases { get; internal set; }
        public ZtUser[] ZtUsers { get; set; }

        internal Cache(ZentaoDbContext context)
        {
            var watch = new Stopwatch();

            watch.Start();
            ZtActions = context.ZtAction.Where(n => n.ObjectType == "bug" || n.ObjectType == "story").ToArray();
            ZtModules = context.ZtModule.Where(n => n.Type == "bug").ToArray();
            ZtBugs = context.ZtBug.ToArray();

            ZtFiles = context.ZtFile.ToArray();

            ZtHistory = context.ZtHistory.ToArray();

            ZtProducts = context.ZtProduct.ToArray();
            ZtReleases = context.ZtRelease.ToArray();

            ZtLangs = context.ZtLang.Where(n => n.Module == "bug" && !string.IsNullOrEmpty(n.Key)).ToArray();

            ZtUsers = context.ZtUser.ToArray();
            ZtGroups = context.ZtGroup.ToArray();
            ZtDepts = context.ZtDept.ToArray();

            watch.Stop();

            var t = watch.ElapsedMilliseconds;

            Console.WriteLine($"缓存加载耗时 {t} ms");
        }

        internal void Dispose()
        {
            ZtActions = Array.Empty<ZtAction>();
            ZtBugs = Array.Empty<ZtBug>();
            ZtDepts = Array.Empty<ZtDept>();
            ZtFiles = Array.Empty<ZtFile>();
            ZtGroups = Array.Empty<ZtGroup>();
            ZtHistory = Array.Empty<ZtHistory>();
            ZtLangs = Array.Empty<ZtLang>();
            ZtModules = Array.Empty<ZtModule>();
            ZtProducts = Array.Empty<ZtProduct>();
            ZtReleases = Array.Empty<ZtRelease>();
            ZtUsers = Array.Empty<ZtUser>();
        }
    }
}